Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(#243): Adds the rank question type #288

Merged
merged 51 commits into from
Jan 31, 2025
Merged

Conversation

latin-panda
Copy link
Collaborator

@latin-panda latin-panda commented Jan 22, 2025

Closes #243

I have verified this PR works in these browsers (latest versions):

  • Chrome
  • Firefox
  • Safari (macOS)
  • Safari (iOS) <I don't have device>
  • Android

What else has been done to verify that this works as intended?

  • I've added demo forms with random, choice-filter, relevant and required
  • It's tested in Android, Chrome for macOS, Safari and Firefox
  • Demo videos has been shared with the team regularly to gather feedback

Why is this the best possible solution? Were any other approaches considered?

This implementation takes select as reference and reuses some of its code.

How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?

  • N/A

Do we need any specific form for testing your changes? If so, please attach one.

Please assist in testing in iOS because I don't have an iPhone or iPad. Other than that, I did the following tests:

Test scenario video: Readonly and translation
The rank question has a condition where it becomes readonly when there are less than 5 options selected. It also gets translated into French.

2-rank-with-choice-filter-read-only.xlsx

readonly-and-translations.mp4
Test scenario video: It should work in all browsers we support. Also, rank as required question.

It works in Chrome, Firefox, Safari and Chrome for Android.
It shows rank working as required questions.

Browser.testing.-.Chrome.Fireforx.Safari.mp4
chrome.for.android.mp4
Test scenario video: Responsive design and becoming relevant again has value assigned

It shows rank in responsive design, where the buttons are hidden for phone devices.
It also tests when the user ordered a rank's options, then it became no-relevant, and relevant again. At this point, the rank has a value assigned, and the user can submit the form without ordering the options again.

responsive.design.and.becoming.relevant.again.has.value.set.mp4

What's changed

  • Added the rank question type in the xform-engine and web forms
  • Added 2 demo rank forms
  • Extracted common code between select and rank
  • New scenario tests were added.

Copy link

changeset-bot bot commented Jan 22, 2025

🦋 Changeset detected

Latest commit: 1232cd8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@getodk/xforms-engine Minor
@getodk/web-forms Minor
@getodk/scenario Minor
@getodk/common Patch
@getodk/xpath Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

yarn.lock Show resolved Hide resolved
@latin-panda
Copy link
Collaborator Author

Hi @eyelidlessness, if you have time, I would really appreciate an early review while I'm working on the test coverage. I'm especially interested in your feedback on the xform-engine implementation.

I manually tested rank and select in Chrome, Firefox, and Safari.

Copy link
Member

@eyelidlessness eyelidlessness left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I've looked at almost all of the engine changes, but I'm going to have to come back to the codecs.

I know there's already a LOT of commentary. I'm not sure how best to provide all the pertinent context without it being overwhelming, so let me know if you'd find it more helpful to jump on a call or something!

Either way, I wanted to share my thoughts so far before my brain runs out of brain juice for the day.

Copy link
Member

@eyelidlessness eyelidlessness left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know there are some changes incoming, particularly on the UI side, so I took a light touch there for now.

And I think I've covered everything that I could on the engine side.

One thing that we'll still need to address is @getodk/scenario. At minimum, it'll need to pass type checks. Mostly that will involve creating and referencing rank-specific equivalents of various things (a good starting point would be to reference select-specific things in scenario package). I think I also mentioned a few specific test cases that would make sense to add. I'm happy to help, I know there's a whole slew of other new concepts to discover there!

@latin-panda All in all, this is an excellent start! I am honestly more than a little mind boggled by how much context you managed to gain on your own with very little information or guidance. I hope the feedback so far is helpful getting this closer to the finish line, and I'm looking forward to taking another pass when you're ready!

@latin-panda latin-panda marked this pull request as ready for review January 29, 2025 21:56
Copy link
Member

@eyelidlessness eyelidlessness left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Submitting another partial round of feedback, before I run out for a break! One small nit on the changeset language, otherwise I think this covers everything I want to in scenario. (Almost all nits there too!)

.changeset/proud-beans-march.md Outdated Show resolved Hide resolved
packages/common/src/test/fixtures/xform-dsl/index.ts Outdated Show resolved Hide resolved
packages/scenario/src/jr/Scenario.ts Show resolved Hide resolved
packages/scenario/test/rank.test.ts Outdated Show resolved Hide resolved
packages/scenario/test/rank.test.ts Outdated Show resolved Hide resolved
packages/scenario/test/rank.test.ts Outdated Show resolved Hide resolved
packages/scenario/test/rank.test.ts Outdated Show resolved Hide resolved
packages/scenario/test/rank.test.ts Show resolved Hide resolved
@latin-panda
Copy link
Collaborator Author

I've attached videos to the PR description about some of the tests I did. Here:


Screenshot 2025-01-30 at 3 58 54 PM

Copy link
Member

@eyelidlessness eyelidlessness left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this wraps up my feedback. Great work @latin-panda! 🎉

I think the only things outstanding are the fix for hasAllValues, and ensuring the test exercising it gets updated to account for the error it'll throw. Otherwise LGTM! I'm excited to get this in.

}

if (highlight.index.value !== null) {
highlight.timeoutID = setTimeout(() => setHighlight(null), 1000);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for any action on this here, just noting a couple things I observed/thought about:

  1. This delay feels longer than I'd expect. And I think tweaking it might be aided by making it a SHOUTY_CONSTANT like HOLD_DELAY is.
  2. There's a pixel shift while the highlight is applied, because the border width changes. I expect we'll make other presentation changes, so I'm not too concerned about it for now.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This delay feels longer than I'd expect. And I think tweaking it might be aided by making it a SHOUTY_CONSTANT like HOLD_DELAY is.

I've added constant with JS Docs, and made it 500ms

There's a pixel shift while the highlight is applied, because the border width changes. I expect we'll make other presentation changes, so I'm not too concerned about it for now.

With the new Figma style, this is not a problem. It's temporary. For now, it looks like the highlight from select, which is a border of 2px


interface HighlightOption {
index: Ref<number | null>;
timeoutID: NodeJS.Timeout | null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely something to solve separately, but this is a really good example of how the TypeScript config is broken for Vue. The type for a web environment should be number | null, and we shouldn't have Node types in scope here at all. Just making note because I've also run into issues with this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! Agree 100%. I tried other types, but I was still getting the errors

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. The config and tooling around Vue is kind of a mess. I've come back to it a few times, but always end up frustrated. Last time I looked, there were a lot of improvements in flight on the tooling front, so maybe I'll take another look at it again soon.

packages/web-forms/src/components/controls/RankControl.vue Outdated Show resolved Hide resolved
Comment on lines +241 to +245
@media screen and (max-width: #{$sm}) {
.rank-buttons {
display: none;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this! The most likely way a user would experience it is on a phone. I think the buttons are especially convenient for a touch interface (where drag/drop can be really awkward, even with finesse like an appropriate delay). I am happy to defer this for now, since it'll probably need more UI/UX design attention. But wanted to note that it feels like a gap to me.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason @alyblenkin and I removed the buttons on mobile devices was to create more space for text and reduce excessive wrapping, which makes reading harder. Buttons take up too much screen space.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's what I assumed. Like I said, I'm happy to defer for now. But I don't think it's the best UX compromise. The place they're hidden is the place I'd want them most. I don't know if that's representative of more users, and that's a good enough reason to me for coming back to it another time! 🚀

packages/scenario/test/rank.test.ts Outdated Show resolved Hide resolved
packages/scenario/test/rank.test.ts Show resolved Hide resolved
@eyelidlessness
Copy link
Member

Just did a quick manual test on my iPhone. Nothing concerning on Safari (iOS)!

Copy link
Member

@eyelidlessness eyelidlessness left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 Awesome awesome work @latin-panda! Feel free to merge once CI passes 🚀

@latin-panda latin-panda merged commit 81a57c3 into main Jan 31, 2025
74 checks passed
@latin-panda
Copy link
Collaborator Author

Thank you for reviewing @eyelidlessness

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add the rank question type
3 participants